home *** CD-ROM | disk | FTP | other *** search
/ Almathera Ten Pack 3: CDPD 3 / Almathera Ten on Ten - Disc 3: CDPD3.iso / fish / 001-100 / 001-025 / 018 / multidim / multidim.c < prev    next >
C/C++ Source or Header  |  1995-03-17  |  13KB  |  436 lines

  1. /*************************************************************************
  2.  *  Version 0.0    MULTIDIM.C - Multi-dimensional rotation    12-Mar-86  *
  3.  *  Commodore Amiga             Main Module                  MULTIDIM.C  *
  4.  *************************************************************************
  5.  *                  Copyright (c) 1986, Robert S. French                 *
  6.  * --------------------------------------------------------------------- *
  7.  *  This program has been placed in the public domain.  A limited        *
  8.  *  license is hereby granted for the unlimited use and distribution of  *
  9.  *  this program, provided it is not used for commercial or profit-      *
  10.  *  making purposes.  Thank you.                                         *
  11.  *************************************************************************
  12.  *  Author information:              |           Disclaimer:             *
  13.  *                                   |                                   *
  14.  *  Name:   Robert S. French         |  The author takes no responsibil- *
  15.  *  USnail: 2740 Frankfort Avenue    |  ity for damages incurred during  *
  16.  *          Louisville, KY  40206    |  the use of this program.         *
  17.  *  Phone:  (502) 897-5096           \-----------------------------------*
  18.  *  ARPA:   French#Robert%d@LLL-MFE     UUCP: ihnp4!ptsfa!well!french    *
  19.  *************************************************************************
  20.  *  Please send any comments, suggestions, or bugs to one of the above   *
  21.  *  addresses.                                                           *
  22.  *************************************************************************
  23.  *                            Comments                                   *
  24.  *                            ========                                   *
  25.  *                                                                       *
  26.  *  Please note that I have very little background in multi-dimensional  *
  27.  *  theory.  This program is not meant to be a scientific representation *
  28.  *  of higher universes, just something kinda neat to look at.  I'm sure *
  29.  *  that there are mathematical problems, such as rotational direction   *
  30.  *  in the higher planes.  "A" etc. are used for lack of better names.   *
  31.  *  Hold the joystick right and press the button to end, or left and     *
  32.  *  press for automatic demo.  Feel free to hack this program up as much *
  33.  *  as you like.  One of the things I'd like to add is double-buffering. *
  34.  *************************************************************************/
  35.  
  36. /* Lots of include files! */
  37.  
  38. #include <exec/types.h> 
  39. #include <exec/tasks.h> 
  40. #include <exec/libraries.h> 
  41. #include <exec/devices.h> 
  42. #include <devices/keymap.h> 
  43. #include <devices/gameport.h>
  44. #include <devices/inputevent.h>
  45. #include <graphics/copper.h> 
  46. #include <graphics/display.h> 
  47. #include <graphics/gfxbase.h> 
  48. #include <graphics/text.h> 
  49. #include <graphics/view.h> 
  50. #include <graphics/gels.h> 
  51. #include <graphics/regions.h> 
  52. #include <hardware/blit.h> 
  53. #include <intuition/intuition.h> 
  54. #include <intuition/intuitionbase.h> 
  55. #include <stdio.h>
  56.  
  57. /* Some definitions... */
  58.  
  59. #define MAXDIM 6
  60. #define MAXPOINTS 64
  61. #define MAXEDGES 250
  62. #define XSCALE 145
  63. #define YSCALE 60
  64. #define XCENTER 320
  65. #define YCENTER 100
  66.  
  67. /* Fast-Floating-Point Definitions... */
  68.  
  69. extern   int     SPFix();
  70. extern   int     SPFlt();
  71. extern   int     SPCmp();
  72. extern   int     SPTst();
  73. extern   int     SPAbs();
  74. extern   int     SPNeg();
  75. extern   int     SPAdd();
  76. extern   int     SPSub();
  77. extern   int     SPMul();
  78. extern   int     SPDiv();
  79.  
  80. extern   int     SPAtan();
  81. extern   int     SPSin();
  82. extern   int     SPCos();
  83. extern   int     SPTan();
  84. extern   int     SPSincos();
  85. extern   int     SPSinh();
  86. extern   int     SPCosh();
  87. extern   int     SPTanh();
  88. extern   int     SPExp();
  89. extern   int     SPLog();
  90. extern   int     SPPow();
  91. extern   int     SPSqrt();
  92. extern   int     SPTieee();
  93. extern   int     SPFieee();
  94.  
  95. /* Other external functions... */
  96.  
  97. extern struct MsgPort *CreatePort();
  98. extern struct IOStdReq *CreateStdIO();      
  99.  
  100. /* And some global graphics stuff... */
  101.  
  102. struct   GfxBase        *GfxBase = NULL;
  103. struct   IntuitionBase  *IntuitionBase = NULL; 
  104.  
  105. struct   Screen   *scrn = NULL;
  106. struct   NewScreen newscreen;
  107. struct   RastPort *rp = NULL;
  108. struct   ViewPort *vp = NULL;
  109.  
  110. /* And some more global stuff... */
  111.  
  112. int MathBase = NULL, MathTransBase = NULL;
  113.  
  114. struct IOStdReq *joystick_io_request = NULL;
  115. struct InputEvent joystick_data;
  116.  
  117. union kludge {
  118.    float f;
  119.    int i;
  120. } points[MAXPOINTS][MAXDIM], xscale, yscale, sqrt2, const2, const15,
  121.   recip2sqrt2;
  122.  
  123. int st_edge[MAXEDGES], end_edge[MAXEDGES], xpoints[MAXPOINTS],
  124.       ypoints[MAXPOINTS];
  125.  
  126. int num_points,num_edges,num_dim,alldim;
  127.  
  128. /* And the real thing... */
  129.  
  130. main(argc,argv)
  131. int argc;
  132. char *argv[];
  133. {
  134.    int i,j,k,num_change,axis1,axis2,autorot,autocount;
  135.    union kludge angle,nangle,pi;
  136.    char *s;
  137.  
  138.    if (argc < 2)
  139.       abort("Usage: multidim n {D}  where n is the number of dimensions");
  140.  
  141.    num_dim = atoi(argv[1]);
  142.    if (num_dim < 2 || num_dim > MAXDIM)
  143.       abort("Illegal number of dimensions");
  144.    alldim = 1;
  145.    if (argc == 3 && toupper(argv[2][0]) == 'D')
  146.       alldim = 0;
  147.  
  148.    if ((MathBase = OpenLibrary("mathffp.library")) == NULL)
  149.       abort("Can't open mathffp.library!");
  150.    if ((MathTransBase = OpenLibrary("mathtrans.library")) == NULL)
  151.       abort("Can't open mathtrans.library!");
  152.  
  153.    xscale.i = SPFlt(XSCALE);
  154.    yscale.i = SPFlt(YSCALE);
  155.    const2.i = SPFlt(2);
  156.    const15.i = SPDiv(SPFlt(2),SPFlt(3));
  157.    sqrt2.i  = SPSqrt(const2.i);
  158.    recip2sqrt2.i = SPDiv(SPMul(SPFlt(2),sqrt2.i),SPFlt(1));
  159.  
  160.    num_points = 1 << num_dim;
  161.  
  162. /* Figure out vertices of n-dimensional "cube" */
  163.  
  164.    for (i=0;i<num_points;i++)
  165.       for (j=0;j<num_dim;j++)
  166.          if (i & (1 << j))
  167.             points[i][j].i = SPFlt(1);
  168.          else
  169.             points[i][j].i = SPFlt(-1);
  170.  
  171. /* Figure out edges */
  172.  
  173.    num_edges = 0;
  174.  
  175.    for (i=0;i<num_points-1;i++)
  176.       for (j=i+1;j<num_points;j++) {
  177.          num_change = 0;
  178.          for (k=0;k<num_dim;k++)
  179.             if (points[i][k].i != points[j][k].i)
  180.                num_change++;
  181.          if (num_change == 1) {
  182.             st_edge[num_edges] = i;
  183.             end_edge[num_edges] = j;
  184.             num_edges++;
  185.          }
  186.       }
  187.  
  188.    if ((IntuitionBase = (struct IntuitionBase *)
  189.         OpenLibrary("intuition.library", 0)) == NULL)
  190.       abort("Can't open Intuition.Library!\n");
  191.    if ((GfxBase = (struct GfxBase *)
  192.         OpenLibrary("graphics.library", 0)) == NULL)
  193.       abort("Can't open Graphics.Library!\n");
  194.  
  195.    open_joystick();
  196.  
  197. /* values for new screen */ 
  198.  
  199.    newscreen.LeftEdge       = 0; 
  200.    newscreen.TopEdge        = 0; 
  201.    newscreen.Width          = 640;
  202.    newscreen.Height         = 200; 
  203.    newscreen.Depth          = 1;
  204.    newscreen.DetailPen      = 0; 
  205.    newscreen.BlockPen       = 1; 
  206.    newscreen.ViewModes      = HIRES;
  207.    newscreen.Type           = CUSTOMSCREEN; 
  208.    newscreen.Font           = NULL;
  209.    newscreen.DefaultTitle   = "";
  210.    newscreen.Gadgets        = NULL; 
  211.     
  212.    scrn = (struct Screen *)OpenScreen(&newscreen);
  213.    if (scrn == 0)
  214.       abort("Can't open new screen!\n");
  215.  
  216.    vp = &(scrn->ViewPort);
  217.    rp = &(scrn->RastPort);
  218.  
  219.    SetAPen(rp,0);
  220.    RectFill(rp,0,0,639,199);
  221.  
  222.    SetRGB4(vp,0,0,0,0);
  223.    SetRGB4(vp,1,0xb,0,0);
  224.  
  225.    SetAPen(rp,1);
  226.    SetBPen(rp,0);
  227.    SetDrMd(rp,JAM2);
  228.    Move(rp,0,9);
  229.    Text(rp,"Plane: X Y",10);
  230.    Move(rp,550,9);
  231.    Text(rp,"R. French",9);
  232.  
  233.    pi.f = 3.1415926535;
  234.    pi.i = SPFieee(pi.i);
  235.  
  236.    angle.i = SPMul(SPDiv(SPFlt(180),pi.i),SPFlt(5));
  237.    nangle.i = SPNeg(angle.i);
  238.  
  239.    axis1 = 0;
  240.    axis2 = 1;
  241.    autorot = autocount = 0;
  242.    s = "   ";
  243.  
  244.    draw();
  245.    while(1) {
  246.       DoIO(joystick_io_request);
  247.       if (joystick_data.ie_Y == 1 && !autorot) {
  248.          rotate(axis1,axis2,nangle.i);
  249.          draw();
  250.       }
  251.       else if (joystick_data.ie_Y == -1 || autorot) {
  252.          rotate(axis1,axis2,angle.i);
  253.          draw();
  254.       }
  255.       if (autorot) autocount = (autocount + 1) % 33;
  256.       if (joystick_data.ie_Code == IECODE_LBUTTON || autocount == 32) {
  257.          if (joystick_data.ie_Code == IECODE_LBUTTON)
  258.             autorot = autocount = 0;
  259.          if (joystick_data.ie_X == 1)
  260.             abort("All done!");
  261.          if (joystick_data.ie_X == -1)
  262.             autorot = 1;
  263.          axis2++;
  264.          if (axis2 > num_dim-1) {
  265.             axis1++;
  266.             if (axis1 > num_dim-2)
  267.                axis1 = 0;
  268.             axis2 = axis1 + 1;
  269.          }
  270.          SetAPen(rp,0);
  271.          RectFill(rp,56,0,85,9);
  272.          SetAPen(rp,1);
  273.          Move(rp,56,9);
  274.          s[0] = (axis1 < 3) ? 'X'+axis1 : 'A'+axis1-3;
  275.          s[2] = (axis2 < 3) ? 'X'+axis2 : 'A'+axis2-3;
  276.          Text(rp,s,3);
  277.       }
  278.    }
  279. }
  280.  
  281. abort(s)
  282. char *s;
  283. {
  284.    puts(s);
  285.    if (joystick_io_request) close_joystick();
  286.    if (scrn) CloseScreen(scrn);
  287.    if (GfxBase) CloseLibrary(GfxBase);
  288.    if (IntuitionBase) CloseLibrary(IntuitionBase);
  289.    if (MathTransBase) CloseLibrary(MathTransBase);
  290.    if (MathBase) CloseLibrary(MathBase);
  291.    exit(20);
  292. }
  293.  
  294. draw()
  295. {
  296.    int i,dim;
  297.    union kludge z;
  298.  
  299.    for (i=0;i<num_points;i++) {
  300.       z.i = SPFlt(1);
  301.  
  302.       if (num_dim > 2)
  303.          if (alldim)
  304.             for (dim=num_dim-1;dim>=2;--dim)
  305.                z.i = SPMul(SPAdd(SPMul(points[i][dim].i,recip2sqrt2.i),
  306.                      const15.i),z.i);
  307.          else
  308.             z.i = SPAdd(SPMul(points[i][num_dim-1].i,recip2sqrt2.i),
  309.                   const15.i);
  310.  
  311.       xpoints[i] = SPFix(SPMul(SPDiv(z.i,points[i][0].i),xscale.i))+XCENTER;
  312.       ypoints[i] = SPFix(SPMul(SPDiv(z.i,points[i][1].i),yscale.i))+YCENTER;
  313.    }
  314.  
  315.    SetAPen(rp,0);
  316.    RectFill(rp,0,10,639,199);
  317.  
  318.    SetAPen(rp,1);
  319.    SetDrMd(rp,JAM1);
  320.  
  321.    for (i=0;i<num_edges;i++) {
  322.       Move(rp,xpoints[st_edge[i]],ypoints[st_edge[i]]);
  323.       Draw(rp,xpoints[end_edge[i]],ypoints[end_edge[i]]);
  324.    }
  325. }
  326.  
  327. rotate(p1,p2,a)
  328. int p1,p2,a;
  329. {
  330.    int i;
  331.    union kludge ang,thesin,thecos,temp1,temp2;
  332.  
  333.    ang.i = a;
  334.  
  335.    thesin.i = SPSin(ang.i);
  336.    thecos.i = SPCos(ang.i);
  337.  
  338.    for (i=0;i<num_points;i++) {
  339.       temp1.i = SPSub(SPMul(points[i][p2].i,thesin.i),
  340.                       SPMul(points[i][p1].i,thecos.i));
  341.       temp2.i = SPAdd(SPMul(points[i][p2].i,thecos.i),
  342.                       SPMul(points[i][p1].i,thesin.i));
  343.       points[i][p1].i = temp1.i;
  344.       points[i][p2].i = temp2.i;
  345.    }
  346. }
  347.  
  348. open_joystick()
  349. {
  350.    struct MsgPort *joystick_msg_port;
  351.  
  352.    /* provide a port for the IO request/response */
  353.  
  354.    joystick_msg_port = CreatePort("thejoystickport",0);
  355.  
  356.    if(joystick_msg_port == 0)
  357.       abort("Can't create joystick port");
  358.  
  359.    /* make an io request block for communicating with the joystick device */
  360.  
  361.    joystick_io_request = CreateStdIO(joystick_msg_port);
  362.  
  363.    if(joystick_io_request == 0)
  364.       abort("Can't create joystick I/O request block");
  365.  
  366.    /* open the gameport device for access, unit 1 is right port */
  367.  
  368.    if(OpenDevice("gameport.device",1,joystick_io_request,0))
  369.       abort("Can't open joystick device");
  370.  
  371.    /* set the device type to absolute joystick */
  372.  
  373.    if (set_controller_type(GPCT_ABSJOYSTICK) != 0)
  374.       abort("Can't set controller type");
  375.  
  376.    /* trigger on button-down, button-up, front, back, left, right, center  */
  377.  
  378.    if (set_controller_trigger(GPTF_UPKEYS+GPTF_DOWNKEYS,1,1,1) != 0)
  379.       abort("Can't set controller trigger");
  380.  
  381.    /* SETUP THE IO MESSAGE BLOCK FOR THE ACTUAL DATA READ */
  382.  
  383.    /* gameport.device replies to this task */
  384.    joystick_io_request->io_Message.mn_ReplyPort = joystick_msg_port;
  385.  
  386.    /* from now on, just read input events */
  387.    joystick_io_request->io_Command = GPD_READEVENT;
  388.  
  389.    /* into the input buffer, one at a time. */
  390.    joystick_io_request->io_Data = (APTR)&joystick_data;
  391.  
  392.    /* read num events each time we go back to the joystickport */
  393.    joystick_io_request->io_Length = sizeof(joystick_data);
  394. }
  395.  
  396. close_joystick()
  397. {
  398.  
  399.     /* close up joystick device */
  400.     
  401.     CloseDevice(joystick_io_request);
  402.  
  403.     /* clean up */
  404.  
  405.     DeletePort(joystick_io_request->io_Message.mn_ReplyPort);
  406.     DeleteStdIO(joystick_io_request);
  407. }
  408.  
  409. int set_controller_type(type)
  410. BYTE type;
  411. {
  412.    joystick_io_request->io_Command = GPD_SETCTYPE;
  413.    joystick_io_request->io_Length = 1;
  414.  
  415.    /* set type of controller to "type" */
  416.    joystick_io_request->io_Data = (APTR)&type;
  417.  
  418.    return(DoIO(joystick_io_request));
  419. }
  420.  
  421. int set_controller_trigger(keys,timeout,xdelta,ydelta)
  422. UWORD keys,timeout,xdelta,ydelta;
  423. {
  424.    struct GamePortTrigger gpt;
  425.  
  426.    joystick_io_request->io_Command = GPD_SETTRIGGER;
  427.    joystick_io_request->io_Length = sizeof(gpt);
  428.    joystick_io_request->io_Data = (APTR)&gpt;
  429.    gpt.gpt_Keys = keys;
  430.    gpt.gpt_Timeout = timeout;
  431.    gpt.gpt_XDelta = xdelta;
  432.    gpt.gpt_YDelta = ydelta;
  433.  
  434.    return(DoIO(joystick_io_request));
  435. }
  436.